package com.blog.controller;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.blog.dao.UserPoJoMapper;
import com.blog.model.Article;
import com.blog.model.ArticleWithBLOBs;
import com.blog.model.Book;
import com.blog.model.Comment;
import com.blog.model.UserPoJo;
import com.blog.model.ViewObject;
import com.blog.service.impl.PublicUtil;
import com.blog.service.impl.UserHolder;
import com.blog.service.interfaces.IBookService;
import com.blog.service.interfaces.ICommentService;
import com.blog.service.interfaces.IConfigService;
import com.blog.service.interfaces.IarticleService;

@Controller
public class IndexController extends BaseTools{
	
	@Autowired
	IarticleService DataBaseMDNum;
	@Autowired
	PublicUtil publicUtil;	
	@Autowired
	UserHolder userHolder;
	@Autowired
	UserPoJoMapper userPoJoMapper;
	@Autowired
	IBookService bookService;
	@Autowired
	ICommentService commentService;		
	@Autowired
	IConfigService configService;
	@Autowired
	ArticleWithBLOBs article;
	@Autowired
	IarticleService articleService;	
	@Autowired
	Book book;
	
	static final Map<String, String> libraryColume ;
	static 
	{//此处改完要改模板   改文件夹 改数据库  改/library/index.html 的js 
	libraryColume= new HashMap<String, String>();
	libraryColume.put("主页", "index");  
	libraryColume.put("编程", "bc"); 
	libraryColume.put("杂谈", "zt"); 
    libraryColume.put("工具", "gj"); 
    libraryColume.put("其他", "qt"); 
    }
	
		/*===============================================
		//主页   /index.html?page={pageId}
		================================================*/
		@RequestMapping(value={"/","/index.html"})
		public String page(@RequestParam(value="page",required=false,defaultValue="1")String pageid,@CookieValue(value="theme",required=false) String theme,Model model,HttpServletRequest request){
			
			/*================================
			 *      检测本地与数据库文章数量是否同步
			 ================================*/
			//检测是否markdown文件已经保存到数据库，如未保存(不相等)则写入数据库
			Integer diskMDNum = configService.getMDNumFromDisk("/articles")[0];
			Integer DataBaseMDNum = articleService.getMdNumFromDB();
			
			if(diskMDNum != DataBaseMDNum){
				if(diskMDNum > DataBaseMDNum){
					//本地文件逐个对比文件与数据库
					for(String fileName : configService.getMDListFromDisk()){
						
						//检测该文章是否已登录到数据库
						//没有登录--添加
						if(articleService.checkExistTitle(fileName).size()==0){
							article.setTitle(fileName);
							article.setContent("markdownflag0/articles/"+fileName+".mdmarkdownflag1");
							article.setPublishTime((int) (System.currentTimeMillis()/1000));
							article.setPopularPoint(100);
							article.setCategory("默认分类");
							article.setCover("http://wx3.sinaimg.cn/cmw205/005LmDmFgy1fr5cvp3s0wj31kw11jh5c.jpg");
							articleService.addArticleTodatabase(article);
						}
					}
				}else{
					//数据库存在冗余文章
					//DataBaseMDNum > diskMDNum
					//数据库逐个对比文件与本地文件
					for(ArticleWithBLOBs DBmd:articleService.getDbMDList()){
						//每一个数据库记录便利所有本地md文件，如找不到对应的删除记录
						int flag11=0;
						for(String fName : configService.getMDListFromDisk()){
							System.out.println(DBmd.getTitle()+"  -   "+fName +"  =   "+DBmd.getTitle().equals(fName));
							if(DBmd.getTitle().equals(fName)){
								flag11=1;
							}
						}
						if(0==flag11){
							articleService.delArticle(DBmd.getId().toString());
						}
					}
				}	
			}
			
			/*================================
			 *      添加类到model
			 ================================*/
			// 添加文章列表list类
			List<ArticleWithBLOBs> tmp=articleService.getArticleFromdatabase(pageid);
			List<ViewObject> vos=new ArrayList<ViewObject>();
			for(ArticleWithBLOBs article:tmp){ 
				ViewObject vo=new ViewObject();//组合对象 解决时间为数值 的问题
				
				if(article.getBrief()==null || article.getBrief().length()<=0){
					//无摘要自动处理
					article.setContent(article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]",""));
					if(article.getContent().length()>70){article.setContent(publicUtil.Html2Text(article.getContent().substring(0,70)).replaceAll(" , ,"," ,").replaceAll(" , ,",",").replaceAll(" , ,"," ,").replaceAll(" , ,"," ,"));}
					if(article.getContent().length()<7){article.setContent("没有简介");}
				}else{
					//有摘要读取数据库摘要
					article.setContent(article.getBrief());
				}
				vo.set("article",article);
				vo.set("time",publicUtil.stampToDate(article.getPublishTime()));
				vo.set("view",articleService.getview(String.valueOf(article.getId())));
				vos.add(vo);
			}
			
			model.addAttribute("articles",vos);
			
			//popular列表list类
			List<ArticleWithBLOBs> tmp2=articleService.getpopularFromdatabase();
			for(ArticleWithBLOBs article:tmp2){ 
				if(article.getTitle().length()>26){article.setTitle(article.getTitle().substring(0,26)+"..");}
			}
			model.addAttribute("populars",tmp2);
			
			//分类list
			model.addAttribute("categorys",articleService.getCategory());

			//页码
			Map<String, String> page=articleService.getPageList(pageid);
			model.addAttribute("pages",page);
			model.addAttribute("username",userHolder.getUserName());
			model.addAttribute("pageid",pageid);
			
			/*================================
			 *      返回页面渲染 根据ua选择页面
			 ================================*/
			if(checkMobile(request.getHeader("USER-AGENT"))){
				return chooseTheme("mobile","wap_theme/index");
			}else{
				return chooseTheme(theme,"index");//选择主题和页面
			}
		}
		
		
		//=============================================================
		//文章详情页  /read/{articleId}
		//访问页面
		@RequestMapping(value = "/read/{id}",method = RequestMethod.GET)
		public String read(@PathVariable(value="id")String articleId,@RequestParam(value="pw",required=false)String pw,@CookieValue(value="theme",required=false) String theme,HttpServletRequest request,Model model)throws Exception{
			ArticleWithBLOBs article;
			try{
			article=articleService.getArticleById(articleId);
			//验证密码访问
			if(article.getPassword()!=null && String.valueOf(article.getPassword()).equals(pw)==false){
				return "redirect:/error/403.htm"; 
			}
			
			articleService.incview(String.valueOf(article.getId()));
 
			
			model.addAttribute("article",article);
			model.addAttribute("comments",commentService.getCommentAndReplyByArticleid(Integer.valueOf(articleId)));
 
			model.addAttribute("time",publicUtil.stampToDate(article.getPublishTime()));
			 
			String ee=article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]","").length()>270?article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]","").substring(0,270):article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]","");
			while(ee.indexOf(" ")!=-1){ee=ee.replaceAll(" ","");}
			while(ee.indexOf(",,")!=-1){ee=ee.replaceAll(",,",",");}
			while(ee.indexOf(",。")!=-1){ee=ee.replaceAll(",。","。");}
			while(ee.indexOf("。,")!=-1){ee=ee.replaceAll("。,","。");}
			model.addAttribute("brief",ee);
			
			model.addAttribute("username",userHolder.getUserName());
			 
			//popular列表list类
			List<ArticleWithBLOBs> tmp2=articleService.getpopularFromdatabase();
			for(ArticleWithBLOBs article2:tmp2){ 
				if(article2.getTitle().length()>26){article2.setTitle(article.getTitle().substring(0,26)+"..");}
			}
			model.addAttribute("populars",tmp2);
			
			if(checkMobile(request.getHeader("USER-AGENT"))){
					return chooseTheme("mobile","wap_theme/read");
			}else{
					return chooseTheme(theme,"read");//选择主题和页面
			}
			
			
			}catch(Exception e){e.printStackTrace();System.out.println("抓到一个异常");return "redirect:../error/404";}
		}
		
		//提交数据到达
		@RequestMapping(value = "/read/{id}",method = RequestMethod.POST)
		public String postComment(@PathVariable(value="id")String articleId,@RequestParam(value="pw",required=false)String pw,@RequestBody Comment comment,@CookieValue(value="theme",required=false) String theme,HttpServletRequest request,Model model) throws Exception{
			comment.setPublish_time((int)(System.currentTimeMillis()/1000));
			if("anonymous".equals(comment.getAuthor_name())==true){
				comment.setAuthor_name("游客");
			}
			commentService.addComment(comment);
			
			return read(articleId, pw, theme, request, model);
		}
		
		//=============================================================
		//文章分类页  /category/{categoryWord}
		@RequestMapping("/category/{categoryWord}")
		public String category(@PathVariable(value="categoryWord")String categoryWord,@CookieValue(value="theme",required=false) String theme,Model model,HttpServletRequest request) {
			try {categoryWord = new String(categoryWord.getBytes("ISO-8859-1"), "utf8");} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码");}  
			List<ArticleWithBLOBs> tmp=articleService.getCategoryArticleFromdatabase(categoryWord);
			List<ViewObject> vos=new ArrayList<ViewObject>();
			for(ArticleWithBLOBs article:tmp){ 
				ViewObject vo=new ViewObject();//组合对象 解决时间为数值 的问题
				
				if(article.getBrief()==null || article.getBrief().length()<=0){
					//无摘要自动处理
					article.setContent(article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]",""));
					if(article.getContent().length()>70){article.setContent(publicUtil.Html2Text(article.getContent().substring(0,70)).replaceAll(" , ,"," ,").replaceAll(" , ,",",").replaceAll(" , ,"," ,").replaceAll(" , ,"," ,"));}
					if(article.getContent().length()<7){article.setContent("没有简介");}
				}else{
					//有摘要读取数据库摘要
					article.setContent(article.getBrief());
				}
				vo.set("article",article);
				vo.set("time",publicUtil.stampToDate(article.getPublishTime()));
				vos.add(vo);
				
				//popular列表list类
				List<ArticleWithBLOBs> tmp2=articleService.getpopularFromdatabase();
				for(ArticleWithBLOBs article2:tmp2){ 
					if(article2.getTitle().length()>26){article2.setTitle(article.getTitle().substring(0,26)+"..");}
				}
				model.addAttribute("populars",tmp2);
				
				
			}
			
			model.addAttribute("articles",vos);
			model.addAttribute("key",categoryWord);
			model.addAttribute("username",userHolder.getUserName());
			if(checkMobile(request.getHeader("USER-AGENT"))){
				return chooseTheme("mobile","wap_theme/index");
			}else{
				return chooseTheme(theme,"category");
			}
		}
		
		//=============================================================
		//文章分类页  /search/{keyWord}
		@RequestMapping("/search")
		public String searchword(@RequestParam(value="word")String keyWord,@CookieValue(value="theme",required=false) String theme,Model model,HttpServletRequest request) {
			try {keyWord = new String(keyWord.getBytes("ISO-8859-1"), "utf8");} catch (UnsupportedEncodingException e) {System.out.println("不支持的编码");}  
			List<ArticleWithBLOBs> tmp=articleService.getSearchResultFromdatabase(keyWord);
			List<ViewObject> vos=new ArrayList<ViewObject>();
			for(ArticleWithBLOBs article:tmp){ 
			ViewObject vo=new ViewObject();//组合对象 解决时间为数值 的问题
						
			article.setContent(article.getContent().replaceAll("[^\u4e00-\u9fa5 ,，。]",""));
			if(article.getContent().length()>70){article.setContent(publicUtil.Html2Text(article.getContent().substring(0,70)));}
			vo.set("article",article);
			vo.set("time",publicUtil.stampToDate(article.getPublishTime()));
			vos.add(vo);
		}
					
			model.addAttribute("articles",vos);
			model.addAttribute("key",keyWord);
			model.addAttribute("username",userHolder.getUserName());
			
			if(checkMobile(request.getHeader("USER-AGENT"))){
				return chooseTheme("mobile","wap_theme/index");
			}else{
				return chooseTheme(theme,"category");//选择主题和页面
			}
		}
		
		//=============================================================
		//图书馆页面  /lib
		@RequestMapping("/lib")
		public String lib(@RequestParam(value="category",required=false)String category,Model model){
			if("".equals(category)==true || category==null){
				category="index";
			}
			
			/*================================
			 *      检测本地与数据库文章数量是否同步
			 ================================*/
			//检测是否markdown文件已经保存到数据库，如未保存(不相等)则写入数据库
			//分类目录已固定要修改需要books文件夹下添加 修改librarycolume 的hashmap
			for(Entry<String, String> colume:libraryColume.entrySet()){
				Integer diskMDNum = configService.getMDNumFromDisk("/books/"+colume.getKey())[0];
				Integer DataBaseMDNum = bookService.getBooksList(colume.getValue()).size();
				
				if(diskMDNum != DataBaseMDNum){
					if(diskMDNum > DataBaseMDNum){
						//本地文件逐个对比文件与数据库
						for(String fileName : configService.getMDListFromDisk()){
							
							//检测该文章是否已登录到数据库
							//没有登录--添加
							if(bookService.checkExistTitle(fileName,colume.getValue()).size()==0){
								book.setBook_id(null);
								book.setBook_category(colume.getValue());
								book.setBook_title(fileName);
								book.setBook_brief("暂无简介");
								book.setBook_url("/lib/read/5");//书籍url
								book.setBook_cover("/files/library/Images/cover.jpg");//封面
								book.setB1("/books/"+colume.getKey()+"/"+fileName+".md");//md文件地址
								bookService.addBook(book);
								
								//System.out.println(book.getBook_id());
								book.setBook_id(book.getBook_id());
								book.setBook_url("/lib/read/"+String.valueOf(book.getBook_id()));
								bookService.updateBookInfo(book);
							}
						}
					}else{
						//数据库存在冗余文章
						//DataBaseMDNum > diskMDNum
						//数据库逐个对比文件与本地文件
						for(Book DBmd:bookService.getBooksList(colume.getValue())){
							//每一个数据库记录便利所有本地md文件，如找不到对应的删除记录
							int flag11=0;
							for(String fName : configService.getMDListFromDisk()){
								System.out.println(DBmd.getBook_title()+"  -   "+fName +"  =   "+DBmd.getBook_title().equals(fName));
								if(DBmd.getBook_title().equals(fName)){
									flag11=1;
								}
							}
							if(0==flag11){
								bookService.delBookById(DBmd.getBook_id().toString());
							}
						}
					}	
				}
			}
			
			model.addAttribute("category",category);
			model.addAttribute("books",bookService.getBooksList(category));
			return "library/index";
		}
		
		//=============================================================
		//图书馆书籍详情页 /lib/read/{id}
		@RequestMapping("/lib/read/{bookid}")
		public String libRead(@PathVariable(value="bookid")String bookid,@RequestParam(required=false,value="pw")String password,Model model,HttpServletRequest request){
			Book book = bookService.selectByBookId(Integer.valueOf(bookid));
			if (null != book ){
				if(null == book.getB2() || password.equals(book.getB2())){
					model.addAttribute("book",book);
					return "library/read";
				}
				return "redirect:/files/error/403.htm"; 
			}
			return "redirect:/files/error/403.htm"; 
		}
		
		
		
		
		
		
		
		//===============================================================
		@RequestMapping("/testvm")
		@ResponseBody
		public String vmTest(Model model){
			System.out.println("读文件测试");
			
			return  ("读文件测试");
		}
		
		@RequestMapping("/test")
		@ResponseBody
		public String testtz(){
			//测试程序判断以类取类是否成功，取不到记录返回null
			UserPoJo user=new UserPoJo();
			user.setUsername("123");
			user.setPassword("123");
			
			System.out.println("!!!!!!1"+userPoJoMapper.selectByUser(user));
			
			MessagePojo<UserPoJo> mp=new MessagePojo<UserPoJo>();
			mp.setState("ok");
			mp.setData(user);
			return JSON.toJSONString(mp);
			
		}
		
}

class MessagePojo<T>{
	public String state="";
	public T data=null;
	public void setState(String state) {
		this.state = state;
	}
	public void setData(T data) {
		this.data = data;
	} 
	
	
}
